home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 297_01 / prtypes.h < prev   
C/C++ Source or Header  |  1991-12-19  |  13KB  |  318 lines

  1. /* prtypes.h */
  2. /* The basic data structures of Small Prolog.
  3.  * This is the file that you need to understand before the others
  4.  * if you want to extend Small Prolog. 
  5.  * 12/21/91 added ND_SUCCESS
  6.  */
  7.  
  8. #include "prolog.h" /* compilation switches */
  9.  
  10. /***************************************************************************
  11.   Variables.
  12.   Variables in Small Prolog begin with a capital letter or an underscore.
  13.   The parser throws away the name and only retains an offset. The variables
  14.   are numbered 0,1,2,... in order of their appearance in a clause. 
  15.   The maximum number of variables is MAX_VAR.
  16.   For optimisation purposes the numbers 0,1,2, etc are multiplied
  17.   by sizeof(struct subst) as soon as the variables are parsed. This
  18.   is the real offset. The offset is used to efficiently lookup the 
  19.   corresponding  molecule in the substitution stack.
  20.  
  21. ****************************************************************************/
  22. typedef int varindx; /* variables have a unique "offset" in a clause */
  23. typedef short clflag_t;/* to contain flags for clauses */
  24.  
  25. /***************************************************************************
  26.  Integers.
  27.  Integers are the same size as pointers.
  28. ***************************************************************************/
  29. typedef long integer; 
  30.  
  31. /***************************************************************************
  32.  Strings.
  33.  Strings are not stored in a hash table, so if you are going to use the
  34.  same string lots of times you better be careful you dont consume too
  35.  much memory.
  36. ***************************************************************************/
  37. typedef char *string_ptr_t;
  38.  
  39. /***************************************************************************
  40.  Reals.
  41.  You might want to just use floats here, but real multiplication usually gets 
  42.  done in doubles anyway.
  43.  You might want to do away with reals altogether.
  44. ***************************************************************************/
  45. typedef double real;
  46. typedef double *real_ptr_t;
  47.  
  48. /****************************************************************************
  49.  Chars . These were added as an afterthought because they were used in an 
  50.  application.
  51.  ****************************************************************************/
  52. typedef unsigned char uchar_t;    /* I prefer insisting on unsigned */
  53.  
  54. /***************************************************************************
  55.  Integer returning functions.
  56.  These are what builtins are made from.
  57.  You will need to be more precise with Zortech C.
  58. ***************************************************************************/
  59. typedef int (* intfun)();
  60.  
  61. /***************************************************************************
  62.  Clauses.
  63.  Clauses are organised in singly linked lists, one for each predicate
  64.  other than a builtin. This does not support an efficient access to a
  65.  clause within a clause packet. Remember that this is just a minimal
  66.  Prolog.
  67.  Each variable comes with a field called nvar_goals which is the
  68.  number of distinct variables in it , multiplied by sizeof(struct subst).
  69.  The number of variables is not going to vary during the execution. Therefore
  70.  so as not to waste time this is stored once and for all so that 
  71.  the right amount of substitution stack can be allocated when this
  72.  clause's head becomes a candidate for unification.
  73.  The Head and Goal of the clause are separated for a small efficiency 
  74.  consideration only.
  75. ***************************************************************************/
  76. typedef struct clause    {
  77.         struct clause *next_clause;/* next in packet or NULL */
  78.         struct node *head_clause;  /* unify goal with this */
  79.         struct node *goals_clause; /* a list if a rule */
  80.         varindx nvar_clause;       /* number of variables */
  81.         clflag_t flags_clause;       /* suplementary flags 
  82.                         I only use this in clean_temp()
  83.                         */
  84.         }*clause_ptr_t;
  85.  
  86. /* C is a clause pointer */
  87. #define CLAUSEPTR_HEAD(C) (C->head_clause) /* returns a nodeptr */
  88. #define CLAUSEPTR_GOALS(C) (C->goals_clause) /* returns a nodeptr */
  89. #define CLAUSEPTR_NVARS(C) (C->nvar_clause)
  90. #define CLAUSEPTR_NEXT(C) (C->next_clause)
  91. #define CLAUSEPTR_FLAGS(C) (C->flags_clause)
  92. #define IS_FACT(C) IS_NIL(CLAUSEPTR_GOALS(C))
  93.  
  94. /***************************************************************************
  95.  Atoms.
  96.  Atoms are identifiers that can serve as relation names or constants.
  97.  Atoms are not to be confused with atomic formulae.
  98.  They have a field which points directly to either a builtin or a 
  99.  clause packet, or just NULL.
  100.  Atoms are stored in a hash table (see prhash.c ).
  101.  In this simple implementation atoms are all stored in the heap,
  102.  and so dont ever disappear on backtracking.
  103. ***************************************************************************/
  104. typedef union    {
  105.         intfun primitive;/* i.e. builtin */
  106.         clause_ptr_t clause;
  107.         }procedure_ptr_t;
  108.  
  109. typedef struct atom    {
  110.         string_ptr_t name;
  111.         struct atom *hash_link; /* in hash table */
  112.         procedure_ptr_t proc;
  113.         } *atom_ptr_t;
  114.  
  115. #define ATOMPTR_BUILTIN(A) (A->proc).primitive
  116. #define ATOMPTR_CLAUSE(A) (A->proc).clause
  117. #define ATOMPTR_NAME(A) (A->name) 
  118.  
  119. /***************************************************************************
  120.  Objects and their types.
  121.  To distinguish integers, reals etc they are stored in "nodes"
  122.  which contains the objects and a type flag. You might want to include
  123.  a mark bit for a garbage collector (see the sourcecode of Xlisp) in the
  124.  type field.
  125.  You will notice that integers are stored directly in an object. This
  126.  avoids an indirection. Variable offsets likewise.
  127. ***************************************************************************/
  128. typedef short objtype_t; /* used to distinguish amongst the types */
  129.  
  130. #ifdef MIX
  131. #undef STRING /* defined in Mix Power C */
  132. #endif
  133.  
  134. /* values for objtype_t - these need to be numbered from 0 up
  135.  * increasing by steps of 1 (see prerror.c , the global
  136.  *  Typenames). Of course this is where enums could be used.
  137.  */
  138. #define ATOM  0
  139. #define VAR  1
  140. #define STRING  2
  141. #define INT  3
  142. #define PAIR  4
  143. #define CLAUSE 5
  144. #define REAL  6
  145. /*
  146. #define CHARACTER 7
  147. */
  148. typedef union  {
  149.         integer int_val;         /* value of integer */
  150.         varindx var_offset;         /* offset of var */
  151.         struct pair *dbl_val;         /* usual value */
  152.         string_ptr_t string_val;    /* pointer to string */
  153.         atom_ptr_t atom_val;        /* pointer to atom */        
  154.         clause_ptr_t clause_val;    /* points to clause */
  155. #ifdef REAL
  156.         real_ptr_t realp_val;         /* pointer to double */
  157. #endif
  158. #ifdef CHARACTER
  159.         uchar_t char_val;        /* char */
  160. #endif
  161.         }obj_ptr_t;
  162.  
  163. /* this is the way we handle objetcs in general - a node
  164.    carries its own type which lets us know how to access 
  165.    the object. A list is made from pairs each of which is
  166.    a couple of nodes.
  167.  */
  168. typedef struct node     {
  169.     objtype_t type;
  170.     obj_ptr_t object;        
  171.     } *node_ptr_t;
  172.  
  173. /* Y is an node_ptr_t */
  174. #define NODEPTR_TYPE(Y) (Y)->type
  175. #define NODEPTR_OBJECT(Y) (Y)->object
  176. #define NODEPTR_ATOM(Y) (NODEPTR_OBJECT(Y)).atom_val
  177. #define NODEPTR_STRING(Y) (NODEPTR_OBJECT(Y)).string_val
  178. #define NODEPTR_OFFSET(Y) (NODEPTR_OBJECT(Y)).var_offset
  179. #define NODEPTR_INT(Y) (NODEPTR_OBJECT(Y)).int_val
  180. #define NODEPTR_PAIR(Y) (NODEPTR_OBJECT(Y)).dbl_val
  181. #define NODEPTR_CLAUSE(Y) (NODEPTR_OBJECT(Y)).clause_val
  182. #define NODEPTR_HEAD(Y) &((((Y)->object).dbl_val)->head)
  183. #define NODEPTR_TAIL(Y) &((((Y)->object).dbl_val)->tail)
  184. #ifdef REAL
  185. #define NODEPTR_REALP(Y) ((NODEPTR_OBJECT(Y)).realp_val)
  186. #define NODEPTR_REAL(Y) *NODEPTR_REALP(Y)
  187. #endif
  188. #ifdef CHARACTER
  189. #define NODEPTR_CHARACTER(Y) (NODEPTR_OBJECT(Y)).char_val
  190. #endif
  191. #define IS_NIL(Y) ((NODEPTR_TYPE(Y)==ATOM) && (NODEPTR_ATOM(Y) == Nil))
  192.  
  193. /***************************************************************************
  194.  Pairs.
  195.  A list is either a pair or the empty list (an atom). This makes
  196.  Small Prolog look like Lisp.
  197.  In Small Prolog all terms are built from lists. This gives uniformity
  198.  at the expense (it seems) of a slight loss of speed. In some implementations
  199.  terms are built as arrays.
  200. ************************